package com.jielin.handling.util.lucene;


import com.jielin.handling.util.FileUtil;
import com.jielin.handling.util.ZipUtil;
import com.jielin.handling.util.pdfutil.RemoveWatermark;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.util.PDFTextStripper;
import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Range;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @Description 创建索引 Lucene 3.0+
 * @Author WR
 * @Date 2020-10-14 13:38
 * @Version 1.0
 */
public class Indexer {

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 保存索引文件的地方
        String indexDir = "C:\\data\\indexDir";
        // 将要搜索TXT文件的地方
        String dateDir = "C:\\data\\recordpdfs";
        IndexWriter indexWriter = null;
        // 创建Directory对象
        Directory dir = new SimpleFSDirectory(new File(indexDir));
//        Directory dir = new SimpleFSDirectory(Paths.get(indexDir));
        // 创建IndexWriter对象,
        // 第一个参数是Directory,第二个是分词器,
        // 第三个表示是否是创建,如果为false为在此基础上面修改,
        // 第四表示表示分词的最大值，比如说new MaxFieldLength(2)，就表示两个字一分，
        // 一般用IndexWriter.MaxFieldLength.LIMITED
        indexWriter = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), true,
                IndexWriter.MaxFieldLength.UNLIMITED);
//        IndexWriterConfig indexWriterConfig = new IndexWriterConfig();
//        indexWriter = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), true,
//                IndexWriterConfig);
        File[] files = new File(dateDir).listFiles();
        for (int i = 0; i < files.length; i++) {
            Document doc = null;
            if (files[i].getName().endsWith(".txt")) {
                doc = new Document();
                // 创建Field对象，并放入doc对象中
                doc.add(new Field("contents", new FileReader(files[i])));
                doc.add(new Field("filename", files[i].getName(),
                        Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.add(new Field("indexDate", DateTools.dateToString(new Date(), DateTools.Resolution.DAY),
                        Field.Store.YES, Field.Index.NOT_ANALYZED));
            } else if (files[i].getName().endsWith(".doc")) {
                doc = getDocument(files[i]);
            } else if (files[i].getName().endsWith(".ppt")) {
                doc = getPPT(files[i]);
            } else if (files[i].getName().endsWith(".xls")) {
                doc = getExcel(files[i]);
            } else if (files[i].getName().endsWith(".pdf")) {
                doc = getPdf(files[i], Boolean.TRUE);
            } else {
                /* 跳过文件夹
                doc = new Document();
                //创建Field对象，并放入doc对象中
                doc.add(new Field("contents", new FileReader(files[i])));
                doc.add(new Field("filename", files[i].getName(),
                        Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.add(new Field("indexDate", DateTools.dateToString(new Date(), DateTools.Resolution.DAY),
                        Field.Store.YES, Field.Index.NOT_ANALYZED));*/

            }
            //写入IndexWriter
            if (doc != null) indexWriter.addDocument(doc);
        }
        //查看IndexWriter里面有多少个索引
        System.out.println("numDocs：" + indexWriter.numDocs());
        indexWriter.close();

    }


    /**
     * 建立笔录内容索引
     */
    public static void IndexerUpdateRecord(String indexDir, List<File> files) throws IOException {
        IndexWriter indexWriter = null;
        // 创建Directory对象
        Directory dir = new SimpleFSDirectory(new File(indexDir));
        // 创建IndexWriter对象,
        // 第一个参数是Directory,第二个是分词器,
        // 第三个表示是否是创建,如果为false为在此基础上面修改,
        // 第四表示表示分词的最大值，比如说new MaxFieldLength(2)，就表示两个字一分，
        // 一般用IndexWriter.MaxFieldLength.LIMITED
        try {
            indexWriter = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), false,
                    IndexWriter.MaxFieldLength.UNLIMITED);
        } catch (FileNotFoundException e) {
            System.out.println("索引文件不存在");
            indexWriter = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), true,
                    IndexWriter.MaxFieldLength.UNLIMITED);
        }
        for (File file : files) {
            Document doc = null;
            if (file.getName().endsWith(".pdf")) {
                doc = getPdf(file, Boolean.TRUE);
            }
            // 写入IndexWriter
//            if (doc != null) indexWriter.addDocument(doc);
            // 避免添加重复索引
            Term fileName = new Term("fileName", file.getName());
            if (doc != null) indexWriter.updateDocument(fileName, doc);
        }
        //查看IndexWriter里面有多少个索引
        System.out.println("numDocs：" + indexWriter.numDocs());
        indexWriter.close();
    }

    public static Document getDocument(File file) throws Exception {
        String docPath = file.getAbsolutePath();
        String title = file.getName();

        // 创建Document
        Document document = new Document();

        /*InputStream inputStream = null;
        Reader contents = null;
        try {
            inputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        WordExtractor extractor = new WordExtractor();
        //try{
        //  POIFSFileSystem fsys = new POIFSFileSystem(inputStream);
        //  DocumentEntry headerProps =
        //           (DocumentEntry)fsys.getRoot().getEntry("WordDocument");
        //  DocumentInputStream din = fsys.createDocumentInputStream("WordDocument");
        //  byte[] header = new byte[headerProps.getSize()];


        //  din.read(header);
        //  din.close();

        //  int info = LittleEndian.getShort(header, 0xa);
        //  if ((info & 0x4) != 0)
        //  {
        //      throw new FastSavedException("Fast-saved files are unsupported at this time");
        //  }
        //  if ((info & 0x100) != 0)
        //  {
        //      throw new PasswordProtectedException("This document is password protected");
        //  }
        //}finally{

        //}

        try {
            contents = new StringReader(extractor.extractText(inputStream));
        } catch (Exception e) {
            e.printStackTrace();
        }*/

        StringBuffer contents = new StringBuffer("");// 文档内容
        try {
            FileInputStream fs = new FileInputStream(docPath);
            HWPFDocument doc = new HWPFDocument(fs);
            Range range = doc.getRange();
            int paragraphCount = range.numParagraphs();// 段落
            for (int i = 0; i < paragraphCount; i++) {// 遍历段落读取数据
                Paragraph pp = range.getParagraph(i);
                contents.append(pp.text());
            }

        } catch (Exception e) {

        }
        String cont = contents.toString().trim();


        document.add(new Field("filename", title, Field.Store.YES,
                Field.Index.ANALYZED));//TOKENIZED
        //document.add(new Field("contents", contents));
        document.add(new Field("contents", cont, Field.Store.YES, Field.Index.ANALYZED));
        //document.add(new Field("path", docPath, Field.Store.YES,Field.Index.ANALYZED));
        document.add(new Field("indexDate", DateTools.dateToString(new Date(), DateTools.Resolution.DAY),
                Field.Store.YES, Field.Index.NOT_ANALYZED));
        return document;
    }

    public static Document getPPT(File pptFile) throws IOException {
        String docPath = pptFile.getAbsolutePath();
        String title = pptFile.getName();


        StringBuffer contents = new StringBuffer("");// 文档内容
        InputStream is = new FileInputStream(pptFile);
        SlideShow ppt = new SlideShow(new HSLFSlideShow(is));
        Slide[] slides = ppt.getSlides();
        //提取文本信息
        /*for (Slide each : slides) {
            //System.out.println("title:" + each.getTitle()) ;
            //System.out.println("content:") ;
            TextRun[] textRuns = each.getTextRuns();
            for (int i=0 ;i< textRuns.length; i++ ) {
                //System.out.println(textRuns[i].getText());
                RichTextRun[] richTextRuns = textRuns[i].getRichTextRuns();
                for (int j = 0; j < richTextRuns.length; j++) {
                    //System.out.println(richTextRuns[j].getText());
                    contents.append(richTextRuns[j].getText());
                }
            }
            contents.append(each.getTitle());
        }*/
        for (int i = 0; i < slides.length; i++) {
            TextRun[] t = slides[i].getTextRuns();//为了取得幻灯片的文字内容，建立TextRun
            for (int j = 0; j < t.length; j++) {
                contents.append(t[j].getText());//这里会将文字内容加到content中去
            }
            //contents.append(slides[i].getTitle());
        }

        Document document = new Document();
        String cont = contents.toString().trim();


        document.add(new Field("filename", title, Field.Store.YES,
                Field.Index.ANALYZED));//TOKENIZED
        //document.add(new Field("contents", contents));
        document.add(new Field("contents", cont, Field.Store.YES, Field.Index.ANALYZED));
        //document.add(new Field("path", docPath, Field.Store.YES,Field.Index.ANALYZED));
        document.add(new Field("indexDate", DateTools.dateToString(new Date(), DateTools.Resolution.DAY),
                Field.Store.YES, Field.Index.NOT_ANALYZED));
        return document;
    }

    /**
     * @param pdf             源文件
     * @param removeWatermark 是否去除笔录水印内容
     * @return
     */
    public static Document getPdf(File pdf, boolean removeWatermark) {
        String pdfPath = pdf.getAbsolutePath();
        // 创建输入流读取pdf文件
        String title = pdf.getName();
        String result = "";
        FileInputStream is = null;
        PDDocument doc = null;
        // 去除笔录水印内容的PDF路径
        String removeWatermarkPDFPath = "";
        try {
            if (removeWatermark) {
                removeWatermarkPDFPath = pdfPath.replace(title, RemoveWatermark.REMOVEWATERMARKTEXT + title);
                RemoveWatermark.removeWatermark(pdfPath, removeWatermarkPDFPath);
                is = new FileInputStream(removeWatermarkPDFPath);
            } else {
                is = new FileInputStream(pdf);
            }
            PDFParser parser = new PDFParser(is);
            parser.parse();
            doc = parser.getPDDocument();
            PDFTextStripper stripper = new PDFTextStripper();
            result = stripper.getText(doc);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (doc != null) {
                try {
                    doc.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (removeWatermark) {
                ZipUtil.deleteFile(new File(removeWatermarkPDFPath));
            }
        }
        Document document = new Document();
        document.add(new Field("filename", title, Field.Store.YES,
                Field.Index.ANALYZED));//TOKENIZED
        document.add(new Field("contents", result, Field.Store.YES,
                Field.Index.ANALYZED));
        //document.add(new Field("path", pdfpath, Field.Store.YES,Field.Index.ANALYZED));
        document.add(new Field("indexDate", DateTools.dateToString(new Date(), DateTools.Resolution.DAY),
                Field.Store.YES, Field.Index.NOT_ANALYZED));
        return document;
    }

    public static Document getExcel(File fileExcel) throws Exception {

        InputStream is = new FileInputStream(fileExcel);
        StringBuffer content = new StringBuffer();

        HSSFWorkbook workbook = new HSSFWorkbook(is);

        for (int numSheets = 0; numSheets < workbook.getNumberOfSheets(); numSheets++) {
            HSSFSheet aSheet = workbook.getSheetAt(numSheets);// 获得一个sheet
            content.append("\n");
            if (null == aSheet) {
                continue;
            }
            for (int rowNum = 0; rowNum <= aSheet.getLastRowNum(); rowNum++) {
                content.append("\n");
                HSSFRow aRow = aSheet.getRow(rowNum);
                if (null == aRow) {
                    continue;
                }

                for (short cellNum = 0; cellNum <= aRow.getLastCellNum(); cellNum++) {
                    HSSFCell aCell = aRow.getCell(cellNum);
                    if (null == aCell) {
                        continue;
                    }

                    if (aCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                        content.append(aCell.getRichStringCellValue().getString());
                    } else if (aCell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                        boolean b = HSSFDateUtil.isCellDateFormatted(aCell);
                        if (b) {
                            Date date = aCell.getDateCellValue();
                            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                            content.append(df.format(date));
                        }
                    }
                }
            }
        }

        String cont = content.toString();
        Document document = new Document();
        document.add(new Field("filename", fileExcel.getName(), Field.Store.YES,
                Field.Index.ANALYZED));//TOKENIZED
        document.add(new Field("contents", cont, Field.Store.YES,
                Field.Index.ANALYZED));
        //document.add(new Field("path", pdfpath, Field.Store.YES,Field.Index.ANALYZED));
        return document;
    }

    public static String readHtml(String urlString) {

        StringBuffer content = new StringBuffer("");
        File file = new File(urlString);
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            // 读取页面
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    fis, "utf-8"));//这里的字符编码要注意，要对上html头文件的一致，否则会出乱码

            String line = null;

            while ((line = reader.readLine()) != null) {
                content.append(line + "\n");
            }
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        String contentString = content.toString();
        return contentString;
    }
}